#include "YGError.h"

namespace YoghurtGum
{

	bool Error::s_FatalError = false;
	char YoghurtGum::Error::s_Explanation[512];


	void Error::Explain(const char* a_Explanation, int a_Line /*= -1*/, char* a_File /*= ""*/, Severity a_Fatality /*= ERROR_NORMAL*/, ...)
	{
		va_list args;
		va_start(args, a_Fatality);

#if (YG_OS_TYPE == YG_OS_TYPE_WINDOWSMOBILE)

		vsprintf(s_Explanation, a_Explanation, args);

#elif (YG_OS_TYPE == YG_OS_TYPE_BADA)

		vsnprintf(s_Explanation, 512, a_Explanation, args);

#endif

		va_end(args);

		Log::GetSingleton().Print("ERROR! %s (line %i in file %s)", s_Explanation, a_Line, a_File);

		if (a_Fatality == ERROR_FATAL)
		{
			Log::GetSingleton().Print("A fatal error occurred.");
		}
	}

	char* Error::GetLastExplanation()
	{
		return s_Explanation;
	}

#if (YG_OS_TYPE == YG_OS_TYPE_WINDOWSMOBILE)

	bool Error::BaseCheck(Flag a_Flag)
	{
		// Error code convention:
		//
		// Convert HRESULT to hex.			
		// -2005532417 -> 0x887600FF
		//
		// failure  module   error
		//   |        |        |
		//   v        v        v
		// 0x8       876      00FF

		// ERROR! TODO: add unsupported error code. [-2005532108](0x88760234)

		switch (a_Flag)
		{

		case ERROR_FILE_NOT_FOUND:
			Log::GetSingleton() << "ERROR! File can't be found. (ERROR_FILE_NOT_FOUND)" << ENDL;
			return true;
			break;
		case ERROR_PATH_NOT_FOUND:
			Log::GetSingleton() << "ERROR! Path can't be found. (ERROR_PATH_NOT_FOUND)" << ENDL;
			return true;
			break;
		case ERROR_INVALID_PARAMETER:
			Log::GetSingleton() << "ERROR! Invalid parameter. (ERROR_INVALID_PARAMETER)" << ENDL;
			return true;
			break;
		case ERROR_INVALID_HANDLE:
			Log::GetSingleton() << "ERROR! The handle is invalid. (ERROR_INVALID_HANDLE)" << ENDL;
			return true;
			break;
		case ERROR_RESOURCE_NAME_NOT_FOUND:
			Log::GetSingleton() << "ERROR! The specified resource name cannot be found in the image file. (ERROR_RESOURCE_NAME_NOT_FOUND)" << ENDL;
			return true;
			break;
		case ERROR_MOD_NOT_FOUND:
			Log::GetSingleton() << "ERROR! The specified module could not be found. (ERROR_MOD_NOT_FOUND)" << ENDL;
			return true;
			break;
		}

		return false;
	}

	bool Error::Failed(Flag a_Status)
	{
		if (FAILED(a_Status)) { BaseCheck(a_Status); return true; }
		return false;
	}

	bool Error::LastError()
	{

#if (YG_OS_TYPE == YG_OS_TYPE_ANDROID)

		return false;

#elif (YG_OS_TYPE == YG_OS_TYPE_WINDOWSMOBILE)

		DWORD status = GetLastError();
		if (status != 0) 
		{ 
			if (!BaseCheck(status)) { DefaultError(status); }
			return true; 
		}
		return false;

#endif

	}

	void Error::DefaultError(Flag a_Flag)
	{
		Log::GetSingleton().Print("ERROR! TODO: add unsupported error code. [%i](0x%x)", a_Flag, a_Flag);
	}

#endif

}; // namespace YoghurtGum
